home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / macintosh technotes and q&as / technotes / tn / samplecode.sit.hqx / Sample Code / StorageLibrary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-22  |  9.6 KB  |  355 lines

  1. /*
  2.     File:        StorageLibrary.c
  3.  
  4.     Contains:    Graphics library for primitive flattening of QuickDraw GX data.
  5.  
  6.     Written by:    Cary Clark, Georgiann Delaney, Michael Fairman, Dave Good,
  7.                 Robert Johnson, Keith McGreggor, Oliver Steele, David Van Brink,
  8.                 Chris Yerga
  9.  
  10.     Copyright:    © 1995-1997 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Writers:
  13.  
  14.         (jtd)    John Daggett
  15.         (DH)    David Hayward
  16.         (cam)    Cameron Esfahani
  17.         (IK)    Ingrid Kelly
  18.  
  19.     Change History (most recent first):
  20.  
  21.          <6>      6/1/97    IK        Modify printing routines for GXGraphics 1.1.6.
  22.          <5>      4/8/97    DH        Added ShapeToFSSpec and FSSpecToShape.
  23.          <4>    10/20/95    jtd        Change ScalerTypes.h ScalerStreamTypes.h.
  24.          <3>     9/21/95    cam        Change BlockMove's to BlockMoveData's.
  25.          <2>      5/1/95    jtd        Bring in final 1.1 source changes.
  26.          <1>      1/9/95    jtd        First checked in.
  27. */
  28.  
  29. #include <Errors.h>
  30. #include <Files.h>
  31. #include <GXFonts.h>
  32. #include <GXGraphics.h>
  33. #include <ScalerTypes.h>
  34.  
  35. #include "StorageLibrary.h"
  36.  
  37. /* ---------------------------------------------------------------------------
  38.     The following routine is an example of how to write a spooling procedure to
  39.     work with GXFlattenShape and GXUnflattenShape. For writing, it stores the data in
  40.     a Handle which must be disposed of after the GXFlattenShape call. When reading,
  41.     it expects the 'data' field of the gxSpoolBlock to have a handle to the data to be
  42.     unflattened.
  43.   --------------------------------------------------------------------------- */
  44.  
  45. #define allocationIncrement    1024    /*    storage handle is grown by this amount */
  46.  
  47. #ifdef __cplusplus
  48. extern "C" {
  49. #endif
  50.  
  51. static long HandleSpoolProc(gxSpoolCommand command, userSpool *block)
  52. {
  53.     switch (command)
  54.     {
  55.         case gxOpenReadSpool:
  56.             block->size = 0;
  57.             block->position = 0;
  58.             break;
  59.  
  60.         case gxOpenWriteSpool:
  61.             block->data = NewHandle(allocationIncrement);
  62.             block->size = allocationIncrement;
  63.             block->position = 0;
  64.             break;
  65.  
  66.         case gxReadSpool:
  67.             BlockMoveData((*(char **) block->data) + block->position, block->spool.buffer, block->spool.count);
  68.             block->position += block->spool.count;
  69.             break;
  70.  
  71.         case gxWriteSpool:
  72.         {
  73.             register long oldPosition;
  74.  
  75.             oldPosition = block->position;
  76.             block->position += block->spool.count;
  77.  
  78.             /*    Make sure there is at least enough room for one buffer size past current pointer. */
  79.  
  80.             if (block->position + block->spool.bufferSize > block->size)        
  81.             {
  82.                 block->size += block->spool.bufferSize;
  83.                 HUnlock((Handle) block->data);
  84.                 SetHandleSize((Handle) block->data, block->size);
  85.                 HLock((Handle) block->data);
  86.             }
  87.             BlockMoveData(block->spool.buffer, (*(char **) block->data + oldPosition), block->spool.count);
  88.             break;
  89.         }
  90.  
  91.         case gxCloseSpool:
  92.             SetHandleSize((Handle) block->data, block->position);
  93.             break;
  94.     }
  95.  
  96.     return 0L;
  97. }
  98.  
  99. #ifdef __cplusplus
  100. }
  101. #endif
  102.  
  103. /* ---------------------------------------------------------------------------
  104.     This routine spools to and from a file.  The file must have previously been created and opened,
  105.     and its refNum is expected to be in the refnum field of the block.
  106.   --------------------------------------------------------------------------- */
  107.  
  108. static long FileSpoolProc(gxSpoolCommand command, userSpool *block)
  109. {
  110.     short err;
  111.     
  112.     switch (command) {
  113.         case gxOpenReadSpool:
  114.         case gxOpenWriteSpool:
  115.             break;
  116.  
  117.         case gxReadSpool:
  118.         {
  119.             long count = block->spool.count;
  120.             err = FSRead(block->reference, &count, block->spool.buffer);
  121. //            IfDebug(err && err != eofErr, "\pFSRead failed");
  122.             break;
  123.         }
  124.  
  125.         case gxWriteSpool:
  126.         {
  127.             long count = block->spool.count;
  128.             err = FSWrite(block->reference, &count, block->spool.buffer);
  129. //            IfDebug(err, "\pFSWrite failed");
  130.             break;
  131.         }
  132.  
  133.         case gxCloseSpool:
  134.             break;
  135.  
  136.         default:
  137. //            IfDebug(true, "\punexpected spool command");
  138.             break;
  139.     }
  140.  
  141.     return 0L;
  142. }
  143.  
  144. /* ---------------------------------------------------------------------------
  145.  
  146.   --------------------------------------------------------------------------- */
  147.  
  148. Handle GXStShapeToHandle(gxShape source)
  149. {
  150.     return GXStShapeToHandleWithFlags(source, gxFontListFlatten | gxFontGlyphsFlatten);
  151. }
  152.  
  153. /* ---------------------------------------------------------------------------
  154.  
  155.   --------------------------------------------------------------------------- */
  156.  
  157. Handle GXStShapeToHandleWithFlags(gxShape source, gxFlattenFlag flags)
  158. {
  159.     userSpool block;
  160.  
  161.     if (source == nil)
  162.     {
  163.         GXPostGraphicsError(shape_is_nil);
  164.         return nil;
  165.     }
  166.  
  167.     block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  168.     block.spool.buffer = nil;
  169.     block.spool.bufferSize = 0;
  170.     GXFlattenShape(source, flags, &block.spool);
  171.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  172.     return (Handle) block.data;
  173. }
  174.  
  175. /* ---------------------------------------------------------------------------
  176.  
  177.   --------------------------------------------------------------------------- */
  178.  
  179. gxShape GXStHandleToShape(Handle source, long count, const gxViewPort portList[])
  180. {
  181.     userSpool block;
  182.     gxShape dest;
  183.     
  184.     block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  185.     block.spool.buffer = nil;
  186.     block.spool.bufferSize = 0;
  187.     block.data = source;
  188.     dest = GXUnflattenShape(&block.spool, count, portList);
  189.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  190.     return dest;
  191. }
  192.  
  193. /* ---------------------------------------------------------------------------
  194.  
  195.   --------------------------------------------------------------------------- */
  196.  
  197. void GXStShapeToFRef(gxShape source, short refNum)
  198. {
  199.     userSpool block;
  200.  
  201.     if (source == nil)
  202.     {
  203.         GXPostGraphicsError(shape_is_nil);
  204.         return;
  205.     }
  206.  
  207.     block.spool.spoolProcedure = NewgxSpoolProc(FileSpoolProc);
  208.     block.reference = refNum;
  209.     block.spool.buffer = nil;
  210.     block.spool.bufferSize = 0;
  211.     GXFlattenShape(source,  gxFontListFlatten | gxFontGlyphsFlatten, &block.spool);
  212.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  213. }
  214.  
  215. /* ---------------------------------------------------------------------------
  216.  
  217.   --------------------------------------------------------------------------- */
  218.  
  219. gxShape GXStFRefToShape(short refNum, long count, const gxViewPort portList[])
  220. {
  221.     userSpool block;
  222.     gxShape dest;
  223.     
  224.     block.spool.spoolProcedure = NewgxSpoolProc(FileSpoolProc);
  225.     block.reference = refNum;
  226.     block.spool.buffer = nil;
  227.     block.spool.bufferSize = 0;
  228.     dest = GXUnflattenShape(&block.spool, count, portList);
  229.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  230.     return dest;
  231. }
  232.  
  233. /* ---------------------------------------------------------------------------
  234.  
  235.   --------------------------------------------------------------------------- */
  236.  
  237. void GXStShapeToFile(gxShape source, Str255 fileName, short vRefNum, OSType creator, OSType fileType)
  238. {
  239.     FSSpec spec;
  240.     short err;
  241.     
  242.     err = FSMakeFSSpec(vRefNum,0,fileName,&spec);
  243. //    IfDebug(err, "\pFSMakeFSSpec failed");
  244.     GXStShapeToFSSpec(source, &spec, creator, fileType, 0);
  245.     return;
  246. }
  247.  
  248. /* ---------------------------------------------------------------------------
  249.  
  250.   --------------------------------------------------------------------------- */
  251.  
  252. gxShape GXStFileToShape(Str255 fileName, short vRefNum, long count, const gxViewPort portList[])
  253. {
  254.     FSSpec spec;
  255.     short err;
  256.     
  257.     err = FSMakeFSSpec(vRefNum,0,fileName,&spec);
  258. //    IfDebug(err, "\pFSMakeFSSpec failed");
  259.     return GXStFSSpecToShape(&spec, count, portList);
  260. }
  261.  
  262. /* ---------------------------------------------------------------------------
  263.  
  264.   --------------------------------------------------------------------------- */
  265.  
  266. void GXStShapeToFSSpec(gxShape source, FSSpec* spec, OSType creator, OSType fileType, ScriptCode script)
  267. {
  268.     short refNum;
  269.     short err;
  270.  
  271.     if (source == nil)
  272.     {
  273.         GXPostGraphicsError(shape_is_nil);
  274.         return;
  275.     }
  276.  
  277.     if (creator == 0) creator = 'sLib';
  278.     if (fileType == 0) fileType = 'flat';
  279.     err = FSpCreate(spec,creator,fileType,script);
  280.     if (err == dupFNErr) {
  281.         err = FSpDelete(spec);
  282. //        IfDebug(err, "\pFSpDelete failed");
  283.         err = FSpCreate(spec,creator,fileType,script);
  284.     }
  285. //    IfDebug(err, "\pFSpCreate failed");
  286.     err = FSpOpenDF(spec,fsWrPerm,&refNum);
  287. //    IfDebug(err, "\pFSpOpenDF failed");
  288.     GXStShapeToFRef(source, refNum);
  289.     err = FSClose(refNum);
  290. //    IfDebug(err, "\pFSClose failed");
  291. }
  292.  
  293. /* ---------------------------------------------------------------------------
  294.  
  295.   --------------------------------------------------------------------------- */
  296.  
  297. gxShape GXStFSSpecToShape(FSSpec* spec, long count, const gxViewPort portList[])
  298. {
  299.     short refNum;
  300.     short err;
  301.     gxShape dest;
  302.  
  303.     if (spec == nil)
  304.     {
  305.         GXPostGraphicsError(parameter_is_nil);
  306.         return nil;
  307.     }
  308.     err = FSpOpenDF(spec, fsCurPerm, &refNum);
  309. //    IfDebug(err, "\pFSpOpenDF failed");
  310.     dest = GXStFRefToShape(refNum, count, portList);
  311.     err = FSClose(refNum);
  312. //    IfDebug(err, "\pFSClose failed");
  313.     return dest;
  314. }
  315.  
  316. /* ---------------------------------------------------------------------------
  317.  
  318.   --------------------------------------------------------------------------- */
  319.  
  320. Handle GXStFontToHandle(gxFont fontID, long glyphBits[])
  321. {
  322.     userSpool block;
  323.     scalerStream stream;
  324.  
  325.     block.spool.spoolProcedure = NewgxSpoolProc(HandleSpoolProc);
  326.     block.spool.buffer = nil;
  327.     block.spool.bufferSize = 0;
  328.  
  329.     stream.streamRefCon = fontID;
  330.     stream.types = type1StreamType;
  331.     stream.action = downloadStreamAction;
  332.     stream.memorySize = 0;
  333.     stream.variationCount = selectAllVariations;
  334.     stream.variations = nil;
  335.     stream.info.font.encoding = 0;
  336.     stream.info.font.glyphBits = glyphBits;
  337.     stream.info.font.name = (char*)"\pSkia-ps";
  338.  
  339.     GXFlattenFont(fontID, &stream, &block.spool);
  340.     DisposeRoutineDescriptor(block.spool.spoolProcedure);
  341.     return (Handle)block.data;
  342. }
  343.  
  344. /* ---------------------------------------------------------------------------
  345.  
  346.   --------------------------------------------------------------------------- */
  347.  
  348. gxFont GXStHandleToFont(Handle source)
  349. {
  350.     /*    GXNewFont does not copy the data in source, so you can't dispose of
  351.         it until you have called GXDisposeFont().
  352.     */
  353.     return GXNewFont(gxHandleFontStorage, source, 0);
  354. }
  355.